﻿namespace Minesweeper {

    public class Minesweeper {

        internal const string MineZeichen = "*";
        internal const string LeeresFeld = " ";

        public static string[,] ErzeugeMogelzettel( string[,] minenfeld) {
            var minenfeldErweitert = ErzeugeErweitertesMinenfeld(minenfeld);
            int[,] attrappenfeld = TesteNachbarnAufMine(minenfeldErweitert);
            return ErzeugeMogelzettelAusAttrappe(attrappenfeld);
        }

        internal static string[,] ErzeugeErweitertesMinenfeld(string[,] minenfeld) {
            var minenfeldErweitert = new string[RowCount(minenfeld) + 2, ColCount(minenfeld) + 2];
            minenfeldErweitert = InitAlsLeeresFeld(minenfeldErweitert);
            minenfeldErweitert = KopiereMinenfeldInErweitertesMinenfeld(minenfeld, minenfeldErweitert);
            return minenfeldErweitert;
        }
        private static string[,] InitAlsLeeresFeld(string[,] minenfeldErweitert) {
            for (int row = 0; row < RowCount(minenfeldErweitert); row++) {
                for (int col = 0; col < ColCount(minenfeldErweitert); col++) {
                    minenfeldErweitert[row, col] = LeeresFeld;
                }
            }
            return minenfeldErweitert;
        }
        private static string[,] KopiereMinenfeldInErweitertesMinenfeld(string[,] minenfeld, string[,] minenfeldErweitert) {
            for (int row = 0; row < RowCount(minenfeld); row++) {
                for (int col = 0; col < ColCount(minenfeld); col++) {
                    minenfeldErweitert[row + 1, col + 1] = minenfeld[row, col];
                }
            }
            return minenfeldErweitert;
        }

        internal static int[,] TesteNachbarnAufMine(string[,] minenfeldErweitert) {

            var attrappenfeld = new int[RowCount(minenfeldErweitert), ColCount(minenfeldErweitert)];

            for (int row = 1; row < RowCount(minenfeldErweitert) - 1; row++) {
                for (int col = 1; col < ColCount(minenfeldErweitert) - 1; col++) {
                    int anzahlMinen = TesteNachbar(row, col, minenfeldErweitert);
                    attrappenfeld[row, col] += anzahlMinen;
                }
            }
            return attrappenfeld;
        }
        private static int TesteNachbar(int row, int col, string[,] minenfeld) {
            int anzahlMinen = 0;
            anzahlMinen += minenfeld[row - 1, col - 1] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row + 1, col + 1] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row - 1, col - 0] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row + 1, col + 0] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row - 1, col + 1] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row + 1, col - 1] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row - 0, col - 1] == MineZeichen ? 1 : 0;
            anzahlMinen += minenfeld[row + 0, col + 1] == MineZeichen ? 1 : 0;
            return anzahlMinen;
        }

        internal  static string[,] ErzeugeMogelzettelAusAttrappe(int[,] attrappenfeld) {
            var mogelzettel = new string[RowCount(attrappenfeld) - 2, ColCount(attrappenfeld) - 2];
            for (int row = 1; row < RowCount(attrappenfeld) - 1; row++) {
                for (int col = 1; col < ColCount(attrappenfeld) - 1; col++)
                    mogelzettel[row - 1, col - 1] = attrappenfeld[row, col].ToString();
            }
            return mogelzettel;
        }

        private static int RowCount<T> (T[,] minenfeld){
            return minenfeld.GetUpperBound(0) + 1; 
        }
        private static int ColCount<T>(T[,] minenfeld) {
            return minenfeld.GetUpperBound(1) + 1;
        }
    }
}
